home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / col / col.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-12-08  |  4.1 KB  |  309 lines

  1. static char *sccsid = "@(#)col.c    4.2 (Berkeley) 5/15/84";
  2. # include <stdio.h>
  3. # define PL 256
  4. # define ESC '\033'
  5. # define RLF '\013'
  6. # define SI '\017'
  7. # define SO '\016'
  8. # define GREEK 0200
  9. # define LINELN 800
  10.  
  11. char *page[PL];
  12. char lbuff [LINELN], *line;
  13. int bflag, hflag, fflag;
  14. int half;
  15. int cp, lp;
  16. int ll, llh, mustwr;
  17. int pcp = 0;
  18. char *pgmname;
  19. char    *strcpy();
  20.  
  21. main (argc, argv)
  22.     int argc; char **argv;
  23. {
  24.     int i;
  25.     int greek;
  26.     register int c;
  27.  
  28.     pgmname = argv[0];
  29.  
  30.     for (i = 1; i < argc; i++) {
  31.         register char *p;
  32.         if (*argv[i] != '-') {
  33.             fprintf (stderr, "%s: bad option %s\n",
  34.                 pgmname, argv[i]);
  35.             exit (2);
  36.         }
  37.         for (p = argv[i]+1; *p; p++) {
  38.             switch (*p) {
  39.             case 'b':
  40.                 bflag++;
  41.                 break;
  42.  
  43.             case 'h':
  44.                 hflag++;
  45.                 break;
  46.  
  47.             case 'f':
  48.                 fflag++;
  49.                 break;
  50.  
  51.             default:
  52.                 fprintf (stderr, "%s: bad option letter %c\n",
  53.                     pgmname, *p);
  54.                 exit (2);
  55.             }
  56.         }
  57.     }
  58.  
  59.     for (ll=0; ll<PL; ll++)
  60.         page[ll] = 0;
  61.  
  62.     cp = 0;
  63.     ll = 0;
  64.     greek = 0;
  65.     mustwr = PL;
  66.     line = lbuff;
  67.  
  68.     while ((c = getchar()) != EOF) {
  69.         switch (c) {
  70.         case '\n':
  71.             incr();
  72.             incr();
  73.             cp = 0;
  74.             continue;
  75.  
  76.         case '\0':
  77.             continue;
  78.  
  79.         case ESC:
  80.             c = getchar();
  81.             switch (c) {
  82.             case '7':    /* reverse full line feed */
  83.                 decr();
  84.                 decr();
  85.                 break;
  86.  
  87.             case '8':    /* reverse half line feed */
  88.                 if (fflag)
  89.                     decr();
  90.                 else {
  91.                     if (--half < -1) {
  92.                         decr();
  93.                         decr();
  94.                         half += 2;
  95.                     }
  96.                 }
  97.                 break;
  98.  
  99.             case '9':    /* forward half line feed */
  100.                 if (fflag)
  101.                     incr();
  102.                 else {
  103.                     if (++half > 0) {
  104.                         incr();
  105.                         incr();
  106.                         half -= 2;
  107.                     }
  108.                 }
  109.                 break;
  110.             }
  111.             continue;
  112.  
  113.         case SO:
  114.             greek = GREEK;
  115.             continue;
  116.  
  117.         case SI:
  118.             greek = 0;
  119.             continue;
  120.  
  121.         case RLF:
  122.             decr();
  123.             decr();
  124.             continue;
  125.  
  126.         case '\r':
  127.             cp = 0;
  128.             continue;
  129.  
  130.         case '\t':
  131.             cp = (cp + 8) & -8;
  132.             continue;
  133.  
  134.         case '\b':
  135.             if (cp > 0)
  136.                 cp--;
  137.             continue;
  138.  
  139.         case ' ':
  140.             cp++;
  141.             continue;
  142.  
  143.         default:
  144.             c &= 0177;
  145.             if (c > 040 && c < 0177) {    /* if printable */
  146.                 outc(c | greek);
  147.                 cp++;
  148.             }
  149.             continue;
  150.         }
  151.     }
  152.  
  153.     for (i=0; i<PL; i++)
  154.         if (page[(mustwr+i)%PL] != 0)
  155.             emit (page[(mustwr+i) % PL], mustwr+i-PL);
  156.     emit (" ", (llh + 1) & -2);
  157.     exit(0);
  158. }
  159.  
  160. outc (c)
  161.     register char c;
  162. {
  163.     if (lp > cp) {
  164.         line = lbuff;
  165.         lp = 0;
  166.     }
  167.  
  168.     while (lp < cp) {
  169.         switch (*line) {
  170.         case '\0':
  171.             *line = ' ';
  172.             lp++;
  173.             break;
  174.  
  175.         case '\b':
  176.             lp--;
  177.             break;
  178.  
  179.         default:
  180.             lp++;
  181.         }
  182.         line++;
  183.     }
  184.     while (*line == '\b') {
  185.         line += 2;
  186.     }
  187.     if (bflag || *line == '\0' || *line == ' ')
  188.         *line = c;
  189.     else {
  190.         register char c1, c2, c3;
  191.         c1 = *++line;
  192.         *line++ = '\b';
  193.         c2 = *line;
  194.         *line++ = c;
  195.         while (c1) {
  196.             c3 = *line;
  197.             *line++ = c1;
  198.             c1 = c2;
  199.             c2 = c3;
  200.         }
  201.         lp = 0;
  202.         line = lbuff;
  203.     }
  204. }
  205.  
  206. store (lno)
  207. {
  208.     char *malloc();
  209.  
  210.     lno %= PL;
  211.     if (page[lno] != 0)
  212.         free (page[lno]);
  213.     page[lno] = malloc((unsigned)strlen(lbuff) + 2);
  214.     if (page[lno] == 0) {
  215.         fprintf (stderr, "%s: no storage\n", pgmname);
  216.         exit (2);
  217.     }
  218.     strcpy (page[lno],lbuff);
  219. }
  220.  
  221. fetch(lno)
  222. {
  223.     register char *p;
  224.  
  225.     lno %= PL;
  226.     p = lbuff;
  227.     while (*p)
  228.         *p++ = '\0';
  229.     line = lbuff;
  230.     lp = 0;
  231.     if (page[lno])
  232.         strcpy (line, page[lno]);
  233. }
  234. emit (s, lineno)
  235.     char *s;
  236.     int lineno;
  237. {
  238.     static int cline = 0;
  239.     register int ncp;
  240.     register char *p;
  241.     static int gflag = 0;
  242.  
  243.     if (*s) {
  244.         while (cline < lineno - 1) {
  245.             putchar ('\n');
  246.             pcp = 0;
  247.             cline += 2;
  248.         }
  249.         if (cline != lineno) {
  250.             putchar (ESC);
  251.             putchar ('9');
  252.             cline++;
  253.         }
  254.         if (pcp)
  255.             putchar ('\r');
  256.         pcp = 0;
  257.         p = s;
  258.         while (*p) {
  259.             ncp = pcp;
  260.             while (*p++ == ' ') {
  261.                 if ((++ncp & 7) == 0 && hflag) {
  262.                     pcp = ncp;
  263.                     putchar ('\t');
  264.                 }
  265.             }
  266.             if (!*--p)
  267.                 break;
  268.             while (pcp < ncp) {
  269.                 putchar (' ');
  270.                 pcp++;
  271.             }
  272.             if (gflag != (*p & GREEK) && *p != '\b') {
  273.                 if (gflag)
  274.                     putchar (SI);
  275.                 else
  276.                     putchar (SO);
  277.                 gflag ^= GREEK;
  278.             }
  279.             putchar (*p & ~GREEK);
  280.             if (*p++ == '\b')
  281.                 pcp--;
  282.             else
  283.                 pcp++;
  284.         }
  285.     }
  286. }
  287.  
  288. incr()
  289. {
  290.     store (ll++);
  291.     if (ll > llh)
  292.         llh = ll;
  293.     if (ll >= mustwr && page[ll%PL]) {
  294.         emit (page[ll%PL], ll - PL);
  295.         mustwr++;
  296.         free (page[ll%PL]);
  297.         page[ll%PL] = 0;
  298.     }
  299.     fetch (ll);
  300. }
  301.  
  302. decr()
  303. {
  304.     if (ll > mustwr - PL) {
  305.         store (ll--);
  306.         fetch (ll);
  307.     }
  308. }
  309.